using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using System;
using System.Collections.Generic;
using W3C.Soap;
using gridslam = Diversity.Robotics.Navigation.GridSlam;


namespace Diversity.Robotics.Navigation.GridSlamService
{
    
    /// <summary>
    /// GridSlam Contract class
    /// </summary>
    public sealed class Contract
    {
        /// <summary>
        /// The Dss Service contract
        /// </summary>
        public const String Identifier = "http://www.diversity.co.uk/2007/05/gridslam.html";
    }
   
    /// <summary>
    /// GridSlam Main Operations Port
    /// </summary>
    public class GridSlamOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Replace>
    {
        /// <summary>
        /// Required Lookup request body type
        /// </summary>
        public virtual PortSet<LookupResponse,Fault> DsspDefaultLookup()
        {
            LookupRequestType body = new LookupRequestType();
            DsspDefaultLookup op = new DsspDefaultLookup(body);
            this.Post(op);
            return op.ResponsePort;

        }
        /// <summary>
        /// Post Dssp Default Lookup and return the response port.
        /// </summary>
        public virtual PortSet<LookupResponse,Fault> DsspDefaultLookup(LookupRequestType body)
        {
            DsspDefaultLookup op = new DsspDefaultLookup();
            op.Body = body ?? new LookupRequestType();
            this.Post(op);
            return op.ResponsePort;

        }
        /// <summary>
        /// A request to drop the service.
        /// </summary>
        public virtual PortSet<DefaultDropResponseType,Fault> DsspDefaultDrop()
        {
            DropRequestType body = new DropRequestType();
            DsspDefaultDrop op = new DsspDefaultDrop(body);
            this.Post(op);
            return op.ResponsePort;

        }
        /// <summary>
        /// Post Dssp Default Drop and return the response port.
        /// </summary>
        public virtual PortSet<DefaultDropResponseType,Fault> DsspDefaultDrop(DropRequestType body)
        {
            DsspDefaultDrop op = new DsspDefaultDrop();
            op.Body = body ?? new DropRequestType();
            this.Post(op);
            return op.ResponsePort;

        }
        /// <summary>
        /// Required Get body type
        /// </summary>
        public virtual PortSet<GridSlamState,Fault> Get()
        {
            GetRequestType body = new GetRequestType();
            Get op = new Get(body);
            this.Post(op);
            return op.ResponsePort;

        }
        /// <summary>
        /// Post Get and return the response port.
        /// </summary>
        public virtual Microsoft.Ccr.Core.PortSet<GridSlamState,Fault> Get(GetRequestType body)
        {
            Get op = new Get();
            op.Body = body ?? new GetRequestType();
            this.Post(op);
            return op.ResponsePort;

        }
    }
    /// <summary>
    /// GridSlam Get Operation
    /// </summary>
    public class Get : Get<GetRequestType, PortSet<GridSlamState, Fault>>
    {
        public Get()
        {
        }
        public Get(GetRequestType body) : 
                base(body)
        {
        }
        public Get(GetRequestType body, PortSet<GridSlamState,Fault> responsePort) : 
                base(body, responsePort)
        {
        }
    }

    /// <summary>
    /// DSS Replace Definition
    /// </summary>
    public class Replace : Replace<GridSlamState, PortSet<DefaultReplaceResponseType, Fault>>
    {
        /// <summary>
        /// Default DSS Get Constructor
        /// </summary>
        public Replace()
        {
        }

        /// <summary>
        /// DSS GridSlamState Constructor
        /// </summary>
        /// <param name="body"></param>
        public Replace(GridSlamState body)
            : base(body)
        {
        }
    }

    public class ProcessData : Update<SlamData, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public ProcessData()
        {
        }

        public ProcessData(SlamData body)
            : base(body)
        {
        }

        public ProcessData(Pose2DState pose, List<DistanceReadingState> readings)
        {
            this.Body = new SlamData(pose,readings);
        }
    }

    [DataContract]
    public class SlamData
    {
        [DataMember] public Pose2DState poseData;
        [DataMember] public List<DistanceReadingState> distanceData;
        public SlamData()
        {
        }
        public SlamData(Pose2DState pose, List<DistanceReadingState> readings)
        {
            this.poseData = pose;
            this.distanceData = readings;
        }
    }

    [DataContract]
    [DataMemberConstructor]
    public class DistanceReadingState
    {
        [DataMember] public double Distance;
        [DataMember] public double AngleOffset;
        [DataMember] public int SensorID;
        public DistanceReadingState()
        {
        }
        public DistanceReadingState(double distance, double angleOffset, int sensorID)
        {
            Distance = distance;
            AngleOffset = angleOffset;
            SensorID = sensorID;
        }
    }

    [DataContract]
    public enum MapType
    {
        RawMap,
        BestMap,
        GlobalMap // only available when world is fake
    }
}
